package com.linkdood.app.web.rest;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.linkdood.app.dto.UploadFileDTO;
import com.linkdood.app.service.AccountService;
import com.linkdood.app.service.UploadFileService;
import com.linkdood.app.utils.PaginationUtil;
import com.linkdood.app.utils.ResourceUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 文件上传
 */
@Api(value = "文件接口", tags = {"文件接口"})
@Slf4j
@RestController
@RequestMapping("/api/files")
public class UploadFileResource {

    private final UploadFileService uploadFileService;

    private final AccountService accountService;

    public UploadFileResource(UploadFileService uploadFileService, AccountService accountService) {
        this.uploadFileService = uploadFileService;
        this.accountService = accountService;
    }

    @PreAuthorize("@ss.hasPermi('bxy:file:upload')")
    @ApiOperation(value = "单文件上传")
    @PostMapping(value = "/single-upload")
    @ResponseBody
    public ResponseEntity<?> uploadSingleFile(@RequestParam(value = "file", required = false) MultipartFile file,
                                              HttpServletRequest request) {
        String currentAccountId = accountService.getCurrentAccountId();
        // 判断是否是分片上传
        String uploadLength = request.getHeader("Upload-Length");
        if (StringUtils.isEmpty(uploadLength)) {
            // 正常上传
            uploadFileService.saveFile(file, currentAccountId);
            return ResponseEntity.ok(ResourceUtil.success());
        } else {
            // 保存分片上传第一条请求记录
            // 前端通过 filepond 来分片上传文件的时候，第一步只上传文件大小，此时需要生成一条记录
            // 之后才对相同或的 URL 通过 PATCH 方法来上传文件数据
            String id = uploadFileService.uploadFragment(Long.parseLong(uploadLength));
            return ResponseEntity.ok(id);
        }
    }

    /**
     * 分片上传中开始分片的接口
     */
    @ApiOperation(value = "分片接口, 需要传文件名、文件长度、分片偏移量和文件分片件内容")
    @PatchMapping(value = "/single-upload")
    @ResponseBody
    public ResponseEntity<?> uploadToLocalAsPatch(@RequestParam("patch") String uploadFileId,
                                                  HttpServletRequest request) {
        String currentAccountId = accountService.getCurrentAccountId();
        uploadFileService.saveFileAsPatch(uploadFileId, request, currentAccountId);
        return ResponseEntity.ok(ResourceUtil.success());
    }

    /**
     * 下载文件链接
     */
    @PreAuthorize("@ss.hasPermi('bxy:file:download')")
    @ApiOperation(value = "下载文件链接")
    @GetMapping("/download-url")
    public ResponseEntity<String> downloadFilesLocation(@RequestParam("id") String id) {
        String currentAccountId = accountService.getCurrentAccountId();
        return ResponseEntity.ok(uploadFileService.getDownloadFileUrl(id, currentAccountId));
    }

    /**
     * 下载文件
     */
    @ApiOperation(value = "下载文件")
    @GetMapping("/download-url/{id}")
    public void downloadFile(@PathVariable("id") String id, HttpServletResponse response) {
        uploadFileService.getDownloadFile(id, response);
    }
    @PreAuthorize("@ss.hasPermi('bxy:file:delete')")
    @ApiOperation(value = "文件删除")
    @DeleteMapping("/{id}")
    @ResponseBody
    public ResponseEntity<?> deleteFiles(@PathVariable String id) {
        uploadFileService.deleteLocalFiles(id);
        return ResponseEntity.ok(ResourceUtil.success());
    }

    /**
     * 文件分页信息
     */
    @PreAuthorize("@ss.hasPermi('bxy:file:index')")
    @ApiOperation(value = "获取所有文件信息")
    @GetMapping
    @ResponseBody
    public ResponseEntity<?> getPageFileOperations(@RequestParam(value = "name", required = false) String name,
                                                   @RequestParam(value = "page", required = false) Integer page,
                                                   @RequestParam(value = "size", required = false) Integer size,
                                                   @RequestParam(value = "sort", required = false) String sort) {
        String currentAccountId = accountService.getCurrentAccountId();
        Page<UploadFileDTO> uploadFiles = uploadFileService.pageUploadFiles(name, page, size, sort, currentAccountId);
        HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(uploadFiles);
        return new ResponseEntity<>(uploadFiles.getRecords(), headers, HttpStatus.OK);
    }

}
